import crypto from 'crypto';
import log4js from 'log4js';
import { toArabicString } from 'chinese-numbers-to-arabic';

const CINEMA_CODE = process.env.CINEMA_CODE || 'Master';

const logFile = './log/' + CINEMA_CODE + '.log';
log4js.configure({
  appenders: {
    consoleOut: {
      type: 'console', // 控制台输出
      layout: {
        type: 'colored', // 使用color模式让控制台输出分类更加鲜明
      },
    },
    [CINEMA_CODE]: {
      type: 'file',
      filename: logFile,
      pattern: 'yyyy-MM-dd.log',
    },
  },
  categories: {
    default: { appenders: ['consoleOut', CINEMA_CODE], level: 'info' },
  },
});
const logger = log4js.getLogger(CINEMA_CODE);

// 生成随机字符串
export function getRandomString(length, withUppercase = false) {
  const chars =
    'abcdefghijklmnopqrstuvwxyz0123456789' + (withUppercase ? 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' : '');
  let result = '';
  const charsLength = chars.length;
  for (let i = 0; i < length; i++) {
    const randomIndex = Math.floor(Math.random() * charsLength);
    result += chars[randomIndex];
  }
  return result;
}

export function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

export function md5(str) {
  return crypto.createHash('md5').update(str).digest('hex');
}

// 记录日志
export function log(str, level = 'info') {
  logger.log(level, str);
}

export function getHallId(hallName, prefix = '') {
  const matchHall = /(\d+号)厅?/.exec(hallName);
  if (matchHall) {
    return md5(prefix + matchHall[1]);
  }
  return md5(prefix + hallName);
}

///* xpath 语法相关工具类
// * /
/**
 * 获取 xpath语法选中的第一个元素
 * @param page
 * @param xpath
 * @returns {Promise<*>}
 */
export async function $x0(page, xpath) {
  let arrayElementHandle = await page.$x(xpath);
  if (arrayElementHandle && arrayElementHandle.length > 0) {
    return arrayElementHandle[0];
  }
  return null;
}

export async function $xClick(page, xpath) {
  let elementHandle = await $x0(page, xpath);
  await elementHandle.click();
}

/**
 * 随机轨迹移动
 * @param page
 * @returns {Promise<void>}
 */
export async function simulateMove(
  page,
  startX,
  startY,
  endX,
  endY,
  options = {}
) {
  const mouse = page.mouse;
  //随机移动 5次以内  随机长度
  let len = await randomInt(5);
  let xNumber = await endX;
  let currentX = 0;
  let xTemp = await randomInt(endX - startX);
  let yTemp = (await startY) + randomInt(5); //下幅度20内  y轴的改变不影响
  for (let i = 0; i < len; i++) {
    await mouse.move(currentX + xTemp, yTemp, options);
    currentX = (await xTemp) + currentX;
    xTemp = await randomInt(endX - startX);
    xNumber = (await xNumber) - xTemp;
    // await  page.waitFor(await randomInt(100, 20));
  }
  //补偿一个直接移动
  await mouse.move(startX + xTemp, endX);
  if (xNumber - startX > 0) {
    await mouse.move(xNumber, yTemp, options);
  }
}

/**
 *  random  范围  (minNumber,maxNumber];   minNumber 默认0
 * @param i
 * @returns {number}
 */
export function randomInt(maxNumber, minNumber) {
  if (!minNumber) {
    minNumber = 0;
  }
  return Math.round(Math.random() * maxNumber) + 1 + minNumber;
}

// 去除影厅关键字
export function subHallName(hallName) {
  let hn = hallName.replace(
    /激光|巨幕|按摩|杜比|全景声|沙发|VPI|商场|负1楼|\s/g,
    ''
  );
  const match = /([\w|一|二|三|四|五|六|七|八|九|零|情侣]+[号|厅])/.exec(hn);
  if (match) {
    return toArabicString(match[1]);
  }

  // 去除括号
  hn = hn.replace(/[（|\(].*[)|）]/g, '');
  // 是否有厅
  const i = hn.indexOf('厅');
  if (i !== -1) {
    return hn.slice(0, i + 1);
  }
  return hn;
}

// 'yyyy-MM-dd hh:mm:ss'
export function timeFormat(date, fmt = 'yyyy-MM-dd hh:mm:ss') {
  const o = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    S: date.getMilliseconds(), // 毫秒
  };
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(
      RegExp.$1,
      (date.getFullYear() + '').substr(4 - RegExp.$1.length)
    );
  }
  for (const k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
      );
    }
  }
  return fmt;
}
